package day12;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @author: 王丹
 * @create: 2021-07-03 16:12
 * ReentrantLock基本使用
 * ReentrantLock的使用过程：
 * 创建锁：ReentrantLock lock = new ReentrantLock();
 * 获取锁：lock.lock()
 * 释放锁：lock.unlock();
 * 对比上面的代码，与关键字synchronized相比，ReentrantLock锁有明显的操作过程，
 * 开发人员必须手动的指定何时加锁，何时释放锁，正是因为这样手动控制，
 * ReentrantLock对逻辑控制的灵活度要远远胜于关键字synchronized，
 * 上面代码需要注意lock.unlock()一定要放在finally中，
 * 否则，若程序出现了异常，锁没有释放，那么其他线程就再也没有机会获取这个锁了。
 **/
public class Demo3 {

    private static int num = 0;

    public static ReentrantLock reentrantLock = new ReentrantLock();

    public static void add() {
        reentrantLock.lock();
        try {
            num++;
        } finally {
            reentrantLock.unlock();
        }
    }

    public static class T extends Thread {
        public void run() {
            for (int i = 0; i < 1000; i++) {
                add();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        T t1 = new T();
        T t2 = new T();
        T t3 = new T();

        t1.start();
        t2.start();
        t3.start();

        t1.join();
        t2.join();
        t3.join();

        System.out.println(num);
    }
}
